#  This is part of the Scopia data visualization example collection
#
#
#  Copyright (C) 2008  Scopia Visual Interfaces Systems 
#                      http://www.scopia.es
#
#  author: Alejandro Conty
#  contributors:
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
import math
from numpy import *
#from scopiavf.font.prerender import PrerenderedText

class LiveGeom(object):
    def render(self, context, *args): pass

lineint = array( ((1.0, 0.0), (0.75, 0.25), (0.5, 0.5), (0.25, 0.75), (0, 1.0)), float32 )

def createIrregularLines( tempjit, tempfin, tempflo, lines, linejit ):
    tempjit[:] = lines[:,newaxis,0] * lineint[:,0][...,newaxis] 
    tempjit[:] += lines[:,newaxis,1] * lineint[:,1][...,newaxis]
    lengths = lines[:,1] - lines[:,0]
    lengths = sqrt(sum(lengths*lengths, axis=1))
    tempjit[:,1:4] += linejit * lengths[...,newaxis,newaxis] * 0.03
    #tempfin = zeros( (tempjit.shape[0], 8, 3 ), float32 )
    tempfin[:,0] = tempjit[:,0]
    tempfin[:,1::2] = tempjit[:,1:]
    tempfin[:,2::2] = tempjit[:,1:-1]
    tempfin.shape = (-1, 3)
    return tempfin

class PointsGeom(LiveGeom):
    def __init__(self, maxpoints):
        self.quads = zeros( (maxpoints, 2, 4, 3), float32 )
        self.quaduvs = zeros( (maxpoints, 2, 4, 2), float32 )
        self.linejit = random.rand(maxpoints, 3, 3)
        rad = 1.0
        self.quads[:,0,0] = ( rad,  rad, 0)
        self.quads[:,0,1] = (-rad,  rad, 0)
        self.quads[:,0,2] = (-rad, -rad, 0)
        self.quads[:,0,3] = ( rad, -rad, 0)
        self.quads[:,1] = self.quads[:,0]
        self.quaduvs[:,0,0] = ( 0.5,  1.0)
        self.quaduvs[:,0,1] = ( 0.0,  1.0)
        self.quaduvs[:,0,2] = ( 0.0,  0.0)
        self.quaduvs[:,0,3] = ( 0.5,  0.0)
        self.quaduvs[:,1,0] = ( 1.0,  1.0)
        self.quaduvs[:,1,1] = ( 0.5,  1.0)
        self.quaduvs[:,1,2] = ( 0.5,  0.0)
        self.quaduvs[:,1,3] = ( 1.0,  0.0)
        jitmov = random.rand(maxpoints, 3) * rad * 0.25
        self.quads[:,0,:,:] += jitmov[...,newaxis,:]
        self.quads[:,1,:,:] -= jitmov[...,newaxis,:]
        jit = random.rand(maxpoints, 2, 4, 3) * rad*0.5
        self.quads += jit
        self.quads.shape = (-1, 8, 3)
        self.quaduvs.shape = (-1, 8, 2)
        self.quadcolors = zeros( (maxpoints, 8, 4), float32 )
        self.quadcolors[:,:] = ( 0, 0, 0, 1.0)
        self.edgecolors = zeros( (maxpoints, 8, 4), float32 )
        self.edgecolors[:,:] = ( 0.0, 0.0, 0, 1.0)
        self.tempJit = zeros( (maxpoints, 5, 3 ), float32 )
        self.tempFin = zeros( (maxpoints, 8, 3 ), float32 )
        self.tempFlo = zeros( (maxpoints, ), float32 )

    def render(self, context, positions, edges, alpha, sizes, mask):
        #print positions
        #sizes = 1.0 / (sqrt(sum(positions*positions, axis=1)) + 1.0)
        l = len(mask)
        sizes = sizes[mask]
        sizes.clip(0.0, 0.015, out = sizes)
        quads = self.quads[:l]*sizes[...,newaxis,newaxis] 
        quads += positions[mask][:,newaxis,...]
        quads.shape = (-1,3)
        #lengths = sqrt(sum(quads * quads, axis=1))
        #quads[:,2] = (lengths*lengths)*0.4
        #lengths = sqrt(sum(edges * edges, axis=1))
        #edges[:,2] = (lengths*lengths)*0.4
        alpha = alpha[mask]
        self.quadcolors[:l,:,3] = alpha[...,newaxis]
        self.edgecolors[:l,:,3] = alpha[...,newaxis]
        context.startTexture('labviz/livetree/res/nodo.png')
        context.setColor(1, 0, 0)
        context.drawQuadArray( quads, colors = self.quadcolors.reshape(-1, 4), uvs = self.quaduvs[:len(positions)].reshape(-1,2) )
        context.endTexture('labviz/livetree/res/nodo.png')
        edges = positions[edges[mask].reshape(-1)]
        lines = createIrregularLines( self.tempJit[:l], self.tempFin[:l], self.tempFlo[:l], edges.reshape(-1,2,3), self.linejit[:l] )
        #lines = edges
        colors = self.edgecolors.reshape(-1, 4)
        for alpha, w in [ (1.0, 1), (0.2, 3)  ]:
            colors[:,3] *= alpha
            context.lineWidth(w)
            context.drawLineArray( lines, colors = colors )

class Style( object ):
    def __init__(self, context):
        self.context = context

    def drawTree( self, context, node, livetree ):
        try: pointsgeom = node.pointsgeom
        except:
            pointsgeom = PointsGeom(livetree.maxelements)
            node.pointsgeom = pointsgeom
        pointsgeom.render(context, livetree.pointBuffer, livetree.edgeBuffer, livetree.alpha, livetree.sizeBuffer, livetree.getMask() )
    
